#include "app_buffer.h"
static void app_buffer_swap(buffer_t *buffer)
{
    int tmp = buffer->read_index;
    buffer->read_index = buffer->write_index;
    buffer->write_index = tmp;
}
static sub_buffer_t *app_sub_buffer_init(int total_size)
{
    sub_buffer_t *sub_buffer = (sub_buffer_t *)malloc(sizeof(sub_buffer_t));
    if (sub_buffer == NULL)
    {
        return NULL;
    }
    memset(sub_buffer, 0, sizeof(sub_buffer_t));
    sub_buffer->ptr = (unsigned char *)malloc(total_size);
    if (sub_buffer->ptr == NULL)
    {
        free(sub_buffer);
        return NULL;
    }
    sub_buffer->total_size = total_size;
    sub_buffer->len = 0;
    return sub_buffer;

}
buffer_t *app_buffer_init(int total_size)
{
    buffer_t *buffer = (buffer_t *)malloc(sizeof(buffer_t));
    if (buffer == NULL)
    {
        return NULL;
    }
    memset(buffer, 0, sizeof(buffer_t));
    buffer->sub_buffers[0] = app_sub_buffer_init(total_size);
    buffer->sub_buffers[1] = app_sub_buffer_init(total_size);
    if (buffer->sub_buffers[0] == NULL || buffer->sub_buffers[1] == NULL)
    {
        free(buffer->sub_buffers[0]);
        free(buffer->sub_buffers[1]);
        free(buffer);
        return NULL;
    }
    buffer->read_index = 0;
    buffer->write_index = 1;

    pthread_mutex_init(&buffer->read_mutex, NULL);
    pthread_mutex_init(&buffer->write_mutex, NULL);
    
    return buffer;
}

void app_buffer_free(buffer_t *buffer)
{
    free(buffer->sub_buffers[0]->ptr);
    free(buffer->sub_buffers[0]);
    free(buffer->sub_buffers[1]->ptr);
    free(buffer->sub_buffers[1]);
    
    //销毁锁
    pthread_mutex_destroy(&buffer->read_mutex);
    pthread_mutex_destroy(&buffer->write_mutex);
    free(buffer);
}

int app_buffer_write(buffer_t *buffer, char *data, int data_len)
{
    if(data_len > MAX_MSG_SIZE)
    {
        log_error("data len is too long");
        return -1;
    }
    pthread_mutex_lock(&buffer->write_mutex);
    sub_buffer_t *sub_buffer = buffer->sub_buffers[buffer->write_index];
    if (sub_buffer->len + data_len > sub_buffer->total_size)
    {
        log_error("sub buffer is full");
        pthread_mutex_unlock(&buffer->write_mutex);
        return -1;
    }
    //将数据的长度写到缓冲区的开头,后面跟数据
    sub_buffer->ptr[sub_buffer->len] = data_len;
    memcpy(sub_buffer->ptr + sub_buffer->len+1, data, data_len);
    sub_buffer->len += (data_len+1);
    //释放锁
    pthread_mutex_unlock(&buffer->write_mutex);
    return 0;
}

int app_buffer_read(buffer_t *buffer, char *data, int len)
{
    pthread_mutex_lock(&buffer->read_mutex);
    sub_buffer_t *read_buffer = buffer->sub_buffers[buffer->read_index];
    if (read_buffer->len <= 0)
    {
        log_info("sub buffer is empty");
        app_buffer_swap(buffer);
        read_buffer = buffer->sub_buffers[buffer->read_index];
        if (read_buffer->len <= 0)
        {
            pthread_mutex_unlock(&buffer->read_mutex);
            return -1;
        }
        
       
    }

    int data_len = read_buffer->ptr[0];
    if (data_len > len)
    {
        log_error("实际读取的数据长度大于期望读取的数据长度");
        pthread_mutex_unlock(&buffer->read_mutex);
        return -1;
    }
    //将数据拷贝到data中
    memcpy(data, read_buffer->ptr+1, data_len);
    //将数据从缓冲区中移除
    int current_len =  read_buffer->len - (data_len+1);
    memmove(read_buffer->ptr, read_buffer->ptr + data_len+1,current_len);
    read_buffer->len -= (data_len+1);
    // memset(read_buffer->ptr + current_len, 0, read_buffer->total_size - current_len);
    pthread_mutex_unlock(&buffer->read_mutex);
    
    return data_len;
}